import numpy as np
from matplotlib import pyplot as plt

def svdimage(filename,percent):
    original=plt.imread(filename)    #读取图像

    R0=np.array(original[:,:,0])     #获取第一层矩阵数据
    G0=np.array(original[:,:,1])     #获取第二层矩阵数据
    B0=np.array(original[:,:,2])     #获取第三层矩阵数据

    u0,sigma0,v0=np.linalg.svd(R0)   #对第一层数据进行SVD分解
    u1,sigma1,v1=np.linalg.svd(G0)   #对第二层数据进行SVD分解
    u2,sigma2,v2=np.linalg.svd(B0)   #对第三层数据进行SVD分解

    R1=np.zeros(R0.shape)
    G1=np.zeros(G0.shape)
    B1=np.zeros(B0.shape)
    total0=sum(sigma0)
    total1=sum(sigma1)
    total2=sum(sigma2)

    sd=0
    for i,sigma in enumerate(sigma0):       #用奇异值总和的百分比来进行筛选。
        R1+=sigma*np.dot(u0[:,i].reshape(-1,1),v0[i,:].reshape(1,-1))
        sd+=sigma
        if sd>=percent*total0:
            break
    sd=0
    for i,sigma in enumerate(sigma1):       #用奇异值总和的百分比来进行筛选
        G1+=sigma*np.dot(u1[:,i].reshape(-1,1),v1[i,:].reshape(1,-1))
        sd+=sigma
        if sd>=percent*total1:
            break
    sd=0
    for i,sigma in enumerate(sigma2): #用奇异值总和的百分比来进行筛选
        B1+=sigma*np.dot(u2[:,i].reshape(-1,1),v2[i,:].reshape(1,-1))
        sd+=sigma
        if sd>=percent*total2:
            break

    final=np.stack((R1,G1,B1),2)                 #合成图片
    final[final>255]=255
    final[final<0]=0
    final=np.rint(final).astype('uint8')
    return final

# for p in np.arange(.1,1,.1):
#     after=svdimage("img.jpg",p)
#     plt.imsave(str(p)+'_1.jpg',after)

# image = svdimage("img.jpg",0.1)
# plt.imshow(image)
# plt.show()

for p in np.arange(.1,1,.2):         #10% 30% 50% 70% 90%
    after=svdimage("img.jpg",p)
    plt.imshow(after)
    plt.show()

'''
1 读取图片，分解成RGB三个矩阵。
2 对三个矩阵分别进行SVD分解，得到对应的奇异值和奇异向量。
3 按照一定标准进行奇异值的筛选（整体数量的一定百分比，或者奇异值和的一定百分比）
4 恢复矩阵，并将RGB三个矩阵叠加起来。
5 保存图像。
'''

